#include <string.h>
#include <iostream>
using std::cout;
using std::ostream;
using std::endl;
//回顾一下深拷贝的string的原理
class String{
public:
    String()
    :_pstr(new char[1]())
    {

    }
    String(const char * pstr)
    :_pstr(new char[strlen(pstr) + 1]())
    {
        strcpy(_pstr, pstr);
    }
    //拷贝构造函数
    String(const String & rhs)
    :_pstr(new char[strlen(rhs._pstr) + 1]())
    {
        cout << "String(const String &)" << endl;
        strcpy(_pstr, rhs._pstr);
    }
    //移动构造函数
    // String s = String("hello");
    // 写的移动构造不能够对左值的对象产生任何影响
    String(String && rhs)
    :_pstr(rhs._pstr)
    {
        cout << "String(&&)" << endl;
        //1.左操作数的指针去指向右值申请的堆空间
        //2.让右值的指针断开和堆空间的联系
        rhs._pstr = nullptr;
    }

    //赋值运算符函数
    String & operator=(const String & rhs){
        cout << "operator=(const String &)" << endl;
        if(this != &rhs){
            delete [] _pstr;
            _pstr = new char[strlen(rhs._pstr) + 1]();
            strcpy(_pstr, rhs._pstr);
        }
        return *this;
    }
    //移动赋值运算符函数
    //
    String & operator=(String && rhs){
        cout << "operator=(&&)" << endl;
        //回收左操作数空间
        delete [] _pstr;
        //浅拷贝
        _pstr = rhs._pstr;
        rhs._pstr = nullptr;
        return *this;
    } 

    ~String(){
        if(_pstr){
            delete [] _pstr;
            _pstr = nullptr;
        }
    }
    friend ostream & operator<<(ostream & os, const String & rhs);

private:
    char * _pstr;
};
ostream & operator<<(ostream & os, const String & rhs){
    if(rhs._pstr){
        os << rhs._pstr;
    }
    return os;
}
void test(){
    //先处理左值
    String s("hello");
    String s2 = s;
    cout << s2 << endl;
    String s3("world");
    s2 = s3;
    cout << s2 << endl;
    cout << "=========================" << endl;

}

void test2(){
    String s4 = String("hello,c++");
    cout << s4 << endl;
    s4 = String("hello,python");
    cout << s4 << endl;
}

int main()
{
    test2();
    return 0;
}

